#include "HttpResponse.h"
#include <iostream>
#include <fstream>
#include <ctime>

using std::cout;
using std::endl;

HttpResponse::HttpResponse()
: _statusCode(HttpStatusCode::OK)
, _version("HTTP/1.1")
{
    setDefaultHeaders();
}

HttpResponse::~HttpResponse()
{
}

void HttpResponse::setStatusCode(HttpStatusCode code)
{
    _statusCode = code;
    _customReason.clear();
}

void HttpResponse::setStatusCode(int code, const string &reason)
{
    _statusCode = static_cast<HttpStatusCode>(code);
    _customReason = reason;
}

void HttpResponse::setHeader(const string &name, const string &value)
{
    _headers[name] = value;
}

void HttpResponse::addHeader(const string &name, const string &value)
{
    auto it = _headers.find(name);
    if (it != _headers.end()) {
        it->second += ", " + value;
    } else {
        _headers[name] = value;
    }
}

string HttpResponse::getHeader(const string &name) const
{
    auto it = _headers.find(name);
    if (it != _headers.end()) {
        return it->second;
    }
    return "";
}

bool HttpResponse::hasHeader(const string &name) const
{
    return _headers.find(name) != _headers.end();
}

void HttpResponse::setBody(const string &body)
{
    _body = body;
    setHeader("Content-Length", std::to_string(_body.length()));
}

void HttpResponse::appendBody(const string &content)
{
    _body += content;
    setHeader("Content-Length", std::to_string(_body.length()));
}

void HttpResponse::setContentType(const string &contentType)
{
    setHeader("Content-Type", contentType);
}

void HttpResponse::enableCORS()
{
    setHeader("Access-Control-Allow-Origin", "*");
    setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
}

void HttpResponse::setJsonContent(const string &json)
{
    setContentType("application/json; charset=utf-8");
    setBody(json);
}

void HttpResponse::setHtmlContent(const string &html)
{
    setContentType("text/html; charset=utf-8");
    setBody(html);
}

void HttpResponse::setPlainTextContent(const string &text)
{
    setContentType("text/plain; charset=utf-8");
    setBody(text);
}

void HttpResponse::setFileContent(const string &filePath)
{
    std::ifstream file(filePath, std::ios::binary);
    if (!file.is_open()) {
        setStatusCode(HttpStatusCode::NOT_FOUND);
        setPlainTextContent("File not found: " + filePath);
        return;
    }
    
    // 读取文件内容
    string content((std::istreambuf_iterator<char>(file)),
                    std::istreambuf_iterator<char>());
    
    // 根据文件扩展名设置Content-Type
    size_t dotPos = filePath.find_last_of('.');
    if (dotPos != string::npos) {
        string extension = filePath.substr(dotPos + 1);
        if (extension == "html" || extension == "htm") {
            setContentType("text/html; charset=utf-8");
        } else if (extension == "css") {
            setContentType("text/css; charset=utf-8");
        } else if (extension == "js") {
            setContentType("application/javascript; charset=utf-8");
        } else if (extension == "json") {
            setContentType("application/json; charset=utf-8");
        } else if (extension == "png") {
            setContentType("image/png");
        } else if (extension == "jpg" || extension == "jpeg") {
            setContentType("image/jpeg");
        } else if (extension == "gif") {
            setContentType("image/gif");
        } else {
            setContentType("application/octet-stream");
        }
    }
    
    setBody(content);
}

string HttpResponse::buildResponse() const
{
    std::ostringstream response;
    
    // 状态行
    string statusText = _customReason.empty() ? 
                       getStatusText(_statusCode) : _customReason;
    response << _version << " " << static_cast<int>(_statusCode) 
             << " " << statusText << "\r\n";
    
    // 响应头
    for (const auto &header : _headers) {
        response << header.first << ": " << header.second << "\r\n";
    }
    
    // 空行分隔头和体
    response << "\r\n";
    
    // 响应体
    response << _body;
    
    return response.str();
}

void HttpResponse::reset()
{
    _statusCode = HttpStatusCode::OK;
    _customReason.clear();
    _headers.clear();
    _body.clear();
    setDefaultHeaders();
}

string HttpResponse::getStatusText(HttpStatusCode code) const
{
    switch (code) {
        case HttpStatusCode::OK: return "OK";
        case HttpStatusCode::CREATED: return "Created";
        case HttpStatusCode::NO_CONTENT: return "No Content";
        case HttpStatusCode::BAD_REQUEST: return "Bad Request";
        case HttpStatusCode::UNAUTHORIZED: return "Unauthorized";
        case HttpStatusCode::FORBIDDEN: return "Forbidden";
        case HttpStatusCode::NOT_FOUND: return "Not Found";
        case HttpStatusCode::METHOD_NOT_ALLOWED: return "Method Not Allowed";
        case HttpStatusCode::INTERNAL_SERVER_ERROR: return "Internal Server Error";
        case HttpStatusCode::NOT_IMPLEMENTED: return "Not Implemented";
        case HttpStatusCode::SERVICE_UNAVAILABLE: return "Service Unavailable";
        default: return "Unknown";
    }
}

void HttpResponse::setDefaultHeaders()
{
    // 设置服务器标识
    setHeader("Server", "MultiReactorHttpServer/1.0");
    
    // 设置时间戳
    std::time_t now = std::time(nullptr);
    char timeBuffer[100];
    std::strftime(timeBuffer, sizeof(timeBuffer), 
                  "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&now));
    setHeader("Date", timeBuffer);
    
    // 设置连接方式
    setHeader("Connection", "keep-alive");
}